﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Vds2465Telegrams
{
	public abstract class UserData_AsciiBytes_Address : UserData_AsciiBytes
	{
		#region constants

		public const int MaxNrOfChars = 30;

		#endregion constants

		#region private member variables

		private readonly bool _relativeAddress;

		#endregion private member variables

		#region constructor

		public UserData_AsciiBytes_Address(byte dataType, string addressString, bool relativeAddress)
			: base(dataType)
		{
			_relativeAddress = relativeAddress;

			byte[] addressBytes;
			if (addressString != null)
			{
				addressBytes = new byte[addressString.Length];
				for (int index = 0; index < addressBytes.Length; index++)
				{
					addressBytes[index] = (byte)(addressString[index]);
				}
			}
			else
			{
				// TODO handle error
				addressBytes = new byte[0];
			}

			HandleAddressBytes(addressBytes, relativeAddress);
		}

		public UserData_AsciiBytes_Address(byte dataType, byte[] addressBytes, bool relativeAddress)
			: base(dataType)
		{
			_relativeAddress = relativeAddress;

			HandleAddressBytes(addressBytes, relativeAddress);
		}

		private void HandleAddressBytes(byte[] addressBytes, bool relativeAddress)
		{
			if (addressBytes != null)
			{
				if (relativeAddress == true)
				{
					// we need one byte for the relative address byte flag
					if (addressBytes.Length < MaxNrOfChars - 1)
					{
						base.SetAsciiBytes(addressBytes);
					}
					else
					{
						// TODO handle error - too many bytes
						byte[] addressBytes_CutOff = new byte[MaxNrOfChars];
						for (int index = 0; index < MaxNrOfChars; index++)
						{
							addressBytes_CutOff[index] = addressBytes[index];
						}

						base.SetAsciiBytes(addressBytes_CutOff);
					}
				}
				else
				{
					if (addressBytes.Length < MaxNrOfChars)
					{
						base.SetAsciiBytes(addressBytes);
					}
					else
					{
						// TODO handle error - too many bytes
						byte[] addressBytes_CutOff = new byte[MaxNrOfChars];
						for (int index = 0; index < MaxNrOfChars; index++)
						{
							addressBytes_CutOff[index] = addressBytes[index];
						}

						base.SetAsciiBytes(addressBytes_CutOff);
					}
				}
			}
			else
			{
				// TODO handle error - addressBytes is null
				base.SetAsciiBytes(null);
			}
		}

		#endregion constructor

		#region getters

		public bool RelativeAddress { get { return _relativeAddress; } }

		#endregion getters

		#region ToString, Equals, GetHashCode

		public override int GetHashCode()
		{
			int hashCode = base.GetHashCode();
			if (RelativeAddress)
			{
				hashCode ^= 0x01;
			}
			return hashCode;
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("(");
			stringBuilder.Append(ToStringProperties());
			stringBuilder.Append(")");

			return stringBuilder.ToString();
		}

		internal override string ToStringProperties()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(base.ToStringProperties());

			stringBuilder.Append(", ");

			stringBuilder.Append("RelativeAddress='");
			stringBuilder.Append(RelativeAddress);
			stringBuilder.Append("'");

			return stringBuilder.ToString();
		}

		public override bool Equals(object obj)
		{
			Type objType = obj.GetType();
			if (this.GetType() == objType)
			{
				UserData_AsciiBytes_Address userData2Compare = obj as UserData_AsciiBytes_Address;
				return EqualsProperties(userData2Compare);
			}

			return false;
		}

		internal bool EqualsProperties(UserData_AsciiBytes_Address userData2Compare)
		{
			if (base.EqualsProperties(userData2Compare))
			{
				return (RelativeAddress == userData2Compare.RelativeAddress);
			}

			return false;
		}

		#endregion ToString, Equals, GetHashCode
	}
}
